#pragma once
#include "socket.hpp"
#include <pthread.h>

class HttpServer;

const std::string wwwroot = "HTML";

struct ThreadData
{
    int _sockfd;
    ThreadData(int sockfd)
        :_sockfd(sockfd)
    {}

};

class HttpServer
{
public:
    HttpServer(uint16_t port = 8080, std::string ip = "0.0.0.0")
        :_port(port), _ip(ip)
    {}

    bool Start()
    {
        Sock ListenSockfd;
        ListenSockfd.Socket();
        ListenSockfd.Bind(_port, _ip);
        ListenSockfd.Listen();
        std::cout << "Listen begin..." << std::endl;
        while(true)
        {
            uint16_t clientport;
            std::string clientip; 
            int sockfd = ListenSockfd.Accept(clientport, clientip);
            if(sockfd < 0) continue;

            pthread_t tid;
            ThreadData* td = new ThreadData(sockfd);
            pthread_create(&tid, nullptr, ThreadRun, td);
        }       
    }

    static void handleHttp(int sockfd)
    {
        char buffer[1024];
        ssize_t n = recv(sockfd, buffer, sizeof(buffer)-1, 0);
        if(n > 0)
        {
            buffer[n] = '\0';
            std::cout << buffer;

            // 响应
            std::string text = "Hello World";
            // std::string text = ReadHtmlContent("HTML/index.html");

            std::string response_line = "HTTP/1.0 200 OK\r\n";
            std::string response_header = "Content-Length: ";
            response_header += std::to_string(text.size());
            response_header += "\r\n";
             
            std::string response = response_line;
            response += response_header;
            response += "\r\n";
            response += text;

            send(sockfd, response.c_str(), response.size(), 0);
        }

        close(sockfd);
    }

    static void* ThreadRun(void* arg)
    {
        ThreadData* td = static_cast<ThreadData*>(arg);
        pthread_detach(pthread_self());

        handleHttp(td->_sockfd);
        

        delete td;
        return nullptr;
    }

    static std::string ReadHtmlContent(std::string path)
    {
        int fd = open(path.c_str(), O_RDONLY);

        std::string content;
        char buffer[1024];
        while(true)
        {
            int n = read(fd, buffer, sizeof(buffer)-1);
            if(n > 0)
            {
                buffer[n] = 0;
                content += buffer;
            } 
            else 
                break;
        } 

        return content;
    }

    ~HttpServer()
    {}

private:
    uint16_t _port;
    std::string _ip;
};